package com.geek.service.impl;

import com.geek.service.*;
import com.geek.mapper.MarketOrderMapper;
import com.geek.model.MarketOrder;
import com.geek.model.MarketOrderExample;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import com.geek.bean.OrderCommentVo;
import com.geek.bean.PageData;
import com.geek.bean.data.*;
import com.geek.mapper.MarketCommentMapper;
import com.geek.mapper.MarketOrderGoodsMapper;
import com.geek.model.*;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

/**
 * @description:
 * @author: yelinbo
 * @date: 2024/06/15 14:05
 **/
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    MarketOrderMapper orderMapper;
    @Autowired
    MarketOrderGoodsMapper ordergoodsMaperr;
    @Autowired
    MarketCommentMapper commentMapper;
    @Autowired
    AddressService addressService;
    @Autowired
    CartService cartService;
    @Autowired
    GoodsProductService goodsProductService;
    @Autowired
    CouponUserService couponUserService;
    @Autowired
    OrderGoodsService orderGoodsService;

    /**
     * 这块需要返回一个pageData 里面的list是订单列表 ；订单列表里面包含了商品列表和操作
     * @param userId
     * @param showType 0 全部 1 待付款 2 待发货 3 待收货 4 待评价
     * @param page
     * @param limit
     * @return
     */
    @Override
    public PageData reListData(Integer userId, Short showType, Integer page, Integer limit) {
        MarketOrderExample orderExample = new MarketOrderExample();
        orderExample.setOrderByClause("add_time desc");
        MarketOrderExample.Criteria criteria = orderExample.createCriteria().andUserIdEqualTo(userId)
                .andDeletedEqualTo(false);
        // 订单状态
        switch (showType){
                            case 0:
                                break;
                            case 1:
                                criteria.andOrderStatusEqualTo(Short.valueOf("101"));
                                break;
                            case 2:
                                criteria.andOrderStatusEqualTo(Short.valueOf("201"));
                                break;
                            case 3:
                                criteria.andOrderStatusEqualTo(Short.valueOf("301"));
                                break;
                            case 4:
                                criteria.andOrderStatusIn(Arrays.asList(Short.valueOf("401"),Short.valueOf("402")));
                                break;
                        }

        PageHelper.startPage(page, limit);
        List<MarketOrder> orderList = orderMapper.selectByExample(orderExample);
        PageData data = PageData.list(orderList);
        List<OrderListData> orderListData = new ArrayList<>();
        // 封装订单列表数据
            for (MarketOrder order : orderList) {
                ArrayList<Object> list = getPayStatusAndHandle(order);
                // goodsList
                MarketOrderGoodsExample marketOrderGoodsExample = new MarketOrderGoodsExample();
                marketOrderGoodsExample.createCriteria()
                        .andDeletedEqualTo(false)
                        .andOrderIdEqualTo(order.getId());
                List<MarketOrderGoods> goodsList = ordergoodsMaperr.selectByExample(marketOrderGoodsExample);
                // 封装商品列表数据
                List<OrderGoodsData> goodsData = new ArrayList<>();
                for (MarketOrderGoods goods : goodsList) {
                    OrderGoodsData orderGoodsData = OrderGoodsData.builder()
                            .goodsName(goods.getGoodsName())
                            .id(goods.getId())
                            .number(goods.getNumber())
                            .picUrl(goods.getPicUrl())
                            .price(goods.getPrice())
                            .specifications(goods.getSpecifications())
                            .build();
                    goodsData.add(orderGoodsData);
                }
                // 封装订单列表数据
                OrderListData orderData = OrderListData.builder()
                        .actualPrice(order.getActualPrice())
                        .aftersaleStatus(order.getAftersaleStatus())
                        // 这块需要封装一个商品列表; OrderGoodsData
                        .goodsList(goodsData)
                        .handleOption((OrderHandleOptionData) list.get(1))
                        // id为订单id
                        .id(order.getId())
                        // 是否拼团 todo 无此功能直接写死
                        .isGroupin(false)
                        .orderSn(order.getOrderSn())
                        .orderStatusText((String) list.get(0))
                        .build();
                orderListData.add(orderData);
            }
            data.setList(orderListData);
        return data;
    }

    private static ArrayList<Object> getPayStatusAndHandle(MarketOrder order) {
        // 判断订单状态
        String orderStatusText = "";
        // 订单操作的
        Boolean cancel = false;
        Boolean confirm = false;
        Boolean delete = false;
        Boolean pay = false;
        Boolean rebuy = false;
        Boolean refund = false;
        Boolean aftersale = false;
        Boolean comment = false;
        switch (order.getOrderStatus()){
            case 101:
                orderStatusText = "待付款";
                cancel = true;
                pay = true;
                break;
            case 102:
                orderStatusText = "用户取消";
                cancel = true;
                delete = true;
                break;
            case 103:
                orderStatusText = "系统取消";
                delete = true;
                cancel = true;
                break;
            case 201:
                orderStatusText = "已付款";
                refund = true;

                break;
            case 202:
                orderStatusText = "申请退款";
                break;
            case 203:
                orderStatusText = "已退款";
                rebuy = true;
                delete = true;
                break;
            case 301:
                orderStatusText = "已发货";
                confirm = true;
                break;
            case 401:
                orderStatusText = "用户收货";
                aftersale = true;
                rebuy = true;
                delete = true;
                if (order.getComments() == 0) {
                    comment = true;
                }
                break;
            case 402:
                orderStatusText = "系统收货";
                aftersale = true;
                // 该值为true且该order_goods没有评论的前提下才会显示该按钮
                if (order.getComments() == 0) {
                    comment = true;
                }
                delete= true;
                rebuy= true;
                break;
        }
        // handleOption
        OrderHandleOptionData handleOptionData = OrderHandleOptionData.builder()
                .aftersale(aftersale)
                .cancel(cancel)
                .comment(comment)
                .confirm(confirm)
                .delete(delete)
                .pay(pay)
                .rebuy(rebuy)
                .refund(refund)
                .build();
        ArrayList<Object> list = new ArrayList<>();
        list.add(orderStatusText);
        list.add(handleOptionData);
        return list;
    }

    @Override
    public OrderDetailData getOrderDetail(Integer orderId) {
        // 封装商品列表数据
        MarketOrderGoodsExample marketOrderGoodsExample = new MarketOrderGoodsExample();
        marketOrderGoodsExample.createCriteria()
                .andDeletedEqualTo(false)
                .andOrderIdEqualTo(orderId);
        List<MarketOrderGoods> goodsList = ordergoodsMaperr.selectByExample(marketOrderGoodsExample);
        MarketOrder marketOrder = orderMapper.selectByPrimaryKey(orderId);
        ArrayList<Object> list = getPayStatusAndHandle(marketOrder);
        Properties properties = new Properties();
        String newproperty = null;
        try {
            properties.load(this.getClass().getClassLoader().getResourceAsStream("express_vendors.properties"));
            if (marketOrder.getShipChannel() != null) {
                String property = properties.getProperty(marketOrder.getShipChannel());
                if (property != null) {
                    newproperty = new String(property.getBytes("ISO-8859-1"), "UTF-8");
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        OrderInfoData infoData = OrderInfoData.builder()
                .actualPrice(marketOrder.getActualPrice())
                .addTime(marketOrder.getAddTime())
                .address(marketOrder.getAddress())
                .aftersaleStatus(marketOrder.getAftersaleStatus())
                .consignee(marketOrder.getConsignee())
                .couponPrice(marketOrder.getCouponPrice())
                .freightPrice(marketOrder.getFreightPrice())
                .goodsPrice(marketOrder.getGoodsPrice())
                // 需要判断
                .handleOption((OrderHandleOptionData) list.get(1))
                .id(orderId)
                .message(marketOrder.getMessage())
                .mobile(marketOrder.getMobile())
                .orderSn(marketOrder.getOrderSn())
                // 需要判断
                .orderStatusText((String) list.get(0))
                .expCode(marketOrder.getShipChannel())
                .expName(newproperty)
                .expNo(marketOrder.getShipSn())
                .build();
        // 封装订单详情数据
        OrderDetailData data = OrderDetailData.builder()
                .orderInfo(infoData)
                .expressInfo(null)
                .orderGoods(goodsList)
                .build();
        return data;
    }
    @Transactional
    @Override
    public void saveComment(OrderCommentVo orderCommentVo,Integer userId) {
        MarketOrderGoodsExample marketOrderGoodsExample = new MarketOrderGoodsExample();
        marketOrderGoodsExample.createCriteria()
                .andDeletedEqualTo(false)
                .andIdEqualTo(orderCommentVo.getOrderGoodsId());
        List<MarketOrderGoods> marketOrderGoodsList = ordergoodsMaperr.selectByExample(marketOrderGoodsExample);
        // 添加comment表中数据
        Date current = new Date();
        MarketComment marketComment = MarketComment.builder()
                .addTime(current)
                .deleted(false)
                .content(orderCommentVo.getContent())
                .star(orderCommentVo.getStar())
                .updateTime(current)
                .picUrls(orderCommentVo.getPicUrls())
                .userId(userId)
                .type((byte) 0)
                .hasPicture(orderCommentVo.isHasPicture())
                // 需要填商品的Id
                .valueId(marketOrderGoodsList != null && marketOrderGoodsList.size() == 1 ? marketOrderGoodsList.get(0).getGoodsId() : null)
                .build();
        commentMapper.insertSelective(marketComment);
        // 修改order_goods表中的comment字段
        marketOrderGoodsExample.clear();
        marketOrderGoodsExample.createCriteria()
                        .andIdEqualTo(orderCommentVo.getOrderGoodsId());
        MarketOrderGoods orderGoods = MarketOrderGoods.builder()
                .comment(marketComment.getId())
                .build();
        ordergoodsMaperr.updateByExampleSelective(orderGoods,marketOrderGoodsExample);
        // 需要修改order表中的comments待评价商品数量
        MarketOrderExample orderExample = new MarketOrderExample();
        orderExample.createCriteria().andIdEqualTo(marketOrderGoodsList.get(0).getOrderId());
        // 先获取 order里面comments原始数据
        List<MarketOrder> marketOrders = orderMapper.selectByExample(orderExample);
        if(marketOrders != null){

            MarketOrder marketOrder = marketOrders.get(0);
            // 需要修改comments字段
            marketOrder.setComments((short) (marketOrder.getComments() - Short.parseShort("1")));
            orderMapper.updateByExampleSelective(marketOrder,orderExample);
        }
    }
    @Transactional
    @Override
    public void cancelOrder(Object orderId) {
        MarketOrderExample example = new MarketOrderExample();
        example.createCriteria().andOrderStatusEqualTo((short) 101)
                .andDeletedEqualTo(false)
                .andIdEqualTo((Integer) orderId);
        MarketOrder marketOrder = MarketOrder.builder()
                .orderStatus((short) 102)
                .build();

        orderMapper.updateByExampleSelective(marketOrder,example);
    }
    @Transactional
    @Override
    public void updateRefund(Object orderId) {
        MarketOrderExample example = new MarketOrderExample();
        example.createCriteria().andOrderStatusEqualTo((short) 201)
                .andDeletedEqualTo(false)
                .andIdEqualTo((Integer) orderId);
        MarketOrder order = orderMapper.selectByPrimaryKey((Integer) orderId);
        MarketOrder marketOrder = MarketOrder.builder()
                .orderStatus((short) 203)
                .refundAmount(order.getActualPrice())
                .refundType("微信退款接口")
                .refundContent(null)
                .refundTime(new Date())
                .build();

        orderMapper.updateByExampleSelective(marketOrder,example);
    }

    @Override
    public void orderDelete(Object orderId) {
        MarketOrderExample example = new MarketOrderExample();
        example.createCriteria().andOrderStatusIn(Arrays.asList(Short.valueOf("401"),Short.valueOf("402")))
                .andDeletedEqualTo(false)
                .andIdEqualTo((Integer) orderId);
        MarketOrder marketOrder = MarketOrder.builder()
                .deleted(true)
                .build();
        orderMapper.updateByExampleSelective(marketOrder,example);
    }
    @Transactional
    @Override
    public void orderConfirm(Object orderId) {
        MarketOrderExample example = new MarketOrderExample();
        example.createCriteria().andIdEqualTo((Integer) orderId)
                .andOrderStatusEqualTo((short)301)
                .andDeletedEqualTo(false);
        MarketOrder marketOrder = MarketOrder.builder()
                .orderStatus((short) 401)
                .build();
        orderMapper.updateByExampleSelective(marketOrder,example);
    }

    @Override
    public MarketOrderGoods orderGoodsByGoodsIdAndOrderId(Integer orderId, Integer goodsId) {
        MarketOrderGoodsExample example = new MarketOrderGoodsExample();
        example.createCriteria().andOrderIdEqualTo(orderId)
                .andDeletedEqualTo(false)
                .andGoodsIdEqualTo(goodsId);
        List<MarketOrderGoods> orderGoodsList = ordergoodsMaperr.selectByExample(example);
        return orderGoodsList != null && orderGoodsList.size() > 0 ? orderGoodsList.get(0) : null;
    }
    @Transactional
    @Override
    public Map<String, Object> submitOrderMessage(Integer userId,RequestOrderSubmitData requestOrderSubmitData,Integer freightMin, Integer freightValue) {
        Map<String, Object> map = new HashMap<>();
        Integer addressId = requestOrderSubmitData.getAddressId();
        Integer cartId = requestOrderSubmitData.getCartId();
        String message = requestOrderSubmitData.getMessage();

        ResponseCheckoutData data;
        int orderId;
        if (cartId == 0){
            data = cartService.cartCheckout(userId,requestOrderSubmitData ,freightMin,freightValue);
            List<MarketCart> cartList = cartService.findCheckedByUserId(userId);
            goodsProductService.updateNumByCartList(cartList);
            cartService.deleteByListIds(cartList);

            Integer couponId = data.getCouponId();
            if (data.getCouponPrice().compareTo(BigDecimal.valueOf(0)) > 0){
                System.out.println("aaaaaaaaaaaaaaaa" + couponId);
                couponUserService.updateCouponStatus(userId, couponId);
            }
            MarketAddress address = addressService.findById(addressId);
            orderId = this.insertBySubmitMessage(userId,address,data,message);
            orderGoodsService.insertByCartSubmit(orderId,cartList);
        }else {
            data = cartService.cartCountByFastadd(userId,requestOrderSubmitData ,freightMin,freightValue);
            MarketCart marketCart = cartService.findById(requestOrderSubmitData.getCartId());
            goodsProductService.updateNumByCart(marketCart);
            cartService.deleteByCartId(requestOrderSubmitData.getCartId());
            if (data.getCouponPrice().compareTo(BigDecimal.valueOf(0)) > 0){
                couponUserService.updateCouponStatus(userId,data.getCouponId());
            }
            MarketAddress address = addressService.findById(addressId);
            orderId = this.insertBySubmitMessage(userId,address,data,message);
            orderGoodsService.insertByFastSubmit(orderId,marketCart);
        }

        map.put("orderId",orderId);
        map.put("grouponLinkId",requestOrderSubmitData.getGrouponLinkId());
        return map;
    }

    @Override
    public int insertBySubmitMessage(Integer userId,MarketAddress address,ResponseCheckoutData data,String message) {
        Date current = new Date();
        String province = (address.getProvince() == null ? "" : address.getProvince());
        String city = (address.getCity() == null ? "" : address.getCity());
        String county = (address.getCounty() == null ? "" : address.getCounty());
        String addressDetail = (address.getAddressDetail() == null ? "" : address.getAddressDetail());
        String addressSum = province + city + county + " " + addressDetail;
        String orderSn = Instant.now().toEpochMilli() + Long.toString((int) (Math.random() * 10000));

        MarketOrder order = MarketOrder.builder().userId(userId)
                .orderSn(orderSn)
                .orderStatus((short) 101)
                .consignee(address.getName())
                .mobile(address.getTel())
                .address(addressSum)
                .goodsPrice(data.getGoodsTotalPrice())
                .freightPrice(data.getFreightPrice())
                .couponPrice(data.getCouponPrice())
                .integralPrice(BigDecimal.valueOf(0))
                .grouponPrice(data.getGrouponPrice())
                .orderPrice(data.getOrderTotalPrice())
                .actualPrice(data.getActualPrice())
                .confirmTime(null)
                .comments((short) 0)
                .endTime(null)
                .message(message)
                .addTime(current)
                .updateTime(current)
                .deleted(false)
                .build();
        MarketOrderExample example = new MarketOrderExample();
        int insert = orderMapper.insert(order);
        example.createCriteria().andDeletedEqualTo(false)
                .andOrderSnEqualTo(order.getOrderSn());
        List<MarketOrder> marketOrders = orderMapper.selectByExample(example);
        Integer id = marketOrders.get(0).getId();
        return id;
    }
}
